Skip to content

Spring 事务传播行为

Propagation枚举,该枚举表示与@Transactional事务注解一起使用的事务传播行为,对应于TransactionDefinition接口。

REQUIRED

支持当前事务,如果不存在则创建一个新事务。这是@Transactional事务注解的默认设置。

假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:

a方法有@Transactional事务注解

如果b方法有Propagation.REQUIRED,结果如下:

  • b加入a的事务

  • 无论哪个方法抛出异常,a和b都会回滚

  • 不能捕获b抛出的异常,否则出现org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only。除非在catch中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();,但a和b仍然都会回滚

a方法没有@Transactional事务注解

如果b方法有Propagation.REQUIRED,结果如下:

  • b创建一个新事务

SUPPORTS

支持当前事务,如果不存在则以非事务方式执行。

假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:

a方法有@Transactional事务注解

如果b方法有Propagation.SUPPORTS,结果如下:

  • b加入a的事务

  • 无论哪个方法抛出异常,a和b都会回滚

  • 不能捕获b抛出的异常,否则出现org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only。除非在catch中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();,但a和b仍然都会回滚

a方法没有@Transactional事务注解

如果b方法有Propagation.SUPPORTS,结果如下:

  • b以非事务方式执行

MANDATORY

支持当前事务,如果不存在则抛出异常。

假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:

a方法有@Transactional事务注解

如果b方法有Propagation.MANDATORY,结果如下:

  • b加入a的事务

  • 无论哪个方法抛出异常,a和b都会回滚

  • 不能捕获b抛出的异常,否则出现org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only。除非在catch中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();,但a和b仍然都会回滚

a方法没有@Transactional事务注解

如果b方法有Propagation.MANDATORY,结果如下:

  • 在调用b时会出现org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'

REQUIRES_NEW

创建一个新事务,如果存在当前事务,则挂起当前事务。

假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:

a方法有@Transactional事务注解

如果b方法有Propagation.REQUIRES_NEW,结果如下:

  • b创建一个新事务,a抛出的异常不会导致b回滚

  • b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚

a方法没有@Transactional事务注解

如果b方法有Propagation.REQUIRES_NEW,结果如下:

  • b创建一个新事务

NOT_SUPPORTED

以非事务方式执行,如果存在当前事务,则暂停当前事务。

假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:

a方法有@Transactional事务注解

如果b方法有Propagation.NOT_SUPPORTED,结果如下:

  • b以非事务方式执行

  • b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚

a方法没有@Transactional事务注解

如果b方法有Propagation.NOT_SUPPORTED,结果如下:

  • b以非事务方式执行

NEVER

以非事务方式执行,如果存在事务则抛出异常。

假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:

a方法有@Transactional事务注解

如果b方法有Propagation.NEVER,结果如下:

  • 在调用b时会出现org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'

  • b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚

a方法没有@Transactional事务注解

如果b方法有Propagation.NEVER,结果如下:

  • b以非事务方式执行

NESTED

如果当前事务存在,则在嵌套事务中执行,否则表现为REQUIRED

假设Service A中的a方法调用Service B中的b方法,这里分为两种情况:

a方法有@Transactional事务注解

如果b方法有Propagation.NESTED,结果如下:

  • b在嵌套事务中执行

  • 无论哪个方法抛出异常,a和b都会回滚

  • 可以捕获b的异常来避免a回滚

a方法没有@Transactional事务注解

如果b方法有Propagation.NESTED,结果如下:

  • b创建一个新事务,以Propagation.REQUIRED传播行为执行

总结

a调用ba有事务且是默认传播行为a没有事务
b事务传播行为是REQUIRED默认传播行为。b加入a的事务。无论哪个方法抛出异常,a和b都会回滚。不能捕获b抛出的异常,否则出现org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only;除非在catch中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();,但a和b仍然都会回滚b创建一个新事务
b事务传播行为是SUPPORTSb加入a的事务。无论哪个方法抛出异常,a和b都会回滚。不能捕获b抛出的异常,否则出现org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only;除非在catch中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();,但a和b仍然都会回滚b以非事务方式执行
b事务传播行为是MANDATORYb加入a的事务。无论哪个方法抛出异常,a和b都会回滚。不能捕获b抛出的异常,否则出现org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only;除非在catch中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();,但a和b仍然都会回滚在调用b时会出现org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
b事务传播行为是REQUIRES_NEWb创建一个新事务,a抛出的异常不会导致b回滚。b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚b创建一个新事务
b事务传播行为是NOT_SUPPORTEDb以非事务方式执行。b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚b以非事务方式执行
b事务传播行为是NEVER在调用b时会出现org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'。b抛出的异常会导致a回滚,可以捕获b抛出的异常来避免a回滚b以非事务方式执行
b事务传播行为是NESTEDb在嵌套事务中执行。无论哪个方法抛出异常,a和b都会回滚。可以捕获b抛出的异常来避免a回滚b创建一个新事务,以Propagation.REQUIRED传播行为执行

Released under the MIT License.